using System.Runtime.CompilerServices;
#if MYCODE
using BepuUtilities.Vectors;
#else
using System.Numerics;
#endif

namespace BepuUtilities
{
    /// <摘要>
    /// 由线性变换和平移组成的变换。
    /// </Summary>
    public struct AffineTransform
    {
        /// <摘要>
        /// 仿射变换中的平移。
        /// </Summary>
        public Vector3 Translation;
        /// <summary>
        /// 仿射变换中的线性变换。
        /// </summary>
        public Matrix3x3 LinearTransform;


        /// <摘要>
        /// 获取标识仿射转换。
        /// </Summary>
        public static AffineTransform Identity
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                var t = new AffineTransform { LinearTransform = Matrix3x3.Identity };
                return t;
            }
        }

        /// <摘要>
        /// 构造一个新的仿射变换。
        /// </Summary>
        /// <param name="翻译">要在转换中使用的翻译。</param>
        public AffineTransform(in Vector3 translation)
        {
            LinearTransform = Matrix3x3.Identity;
            Translation = translation;
        }

        /// <摘要>
        /// 构造了一个新的仿射变换。
        /// </Summary>
        /// <param name="Orientation">用作线性转换的方向。</param>
        /// <param name="翻译">要在转换中使用的翻译。</param>
        public AffineTransform(in Quaternion orientation, in Vector3 translation)
        {
            Matrix3x3.CreateFromQuaternion(orientation, out LinearTransform);
            Translation = translation;
        }

        /// <摘要>
        /// 构造一个新的仿射变换。
        /// </Summary>
        /// <param name="scaling">要在线性转换中应用的缩放。</param>
        /// <param name="Orientation">要在线性变换中应用的方向。</param>
        /// <param name="翻译">要应用的翻译。</param>
        public AffineTransform(in Vector3 scaling, in Quaternion orientation, in Vector3 translation)
        {
            // 创建SRT转换。
            Matrix3x3.CreateScale(scaling, out LinearTransform);
            Matrix3x3.CreateFromQuaternion(orientation, out var rotation);
            Matrix3x3.Multiply(LinearTransform, rotation, out LinearTransform);
            Translation = translation;
        }

         /// <摘要>
        /// 构造一个新的仿射变换。
        /// </Summary>
        /// <param name="linearTransform">线性转换组件。</param>
        /// <param name="翻译">转换的翻译组件。</param>
        public AffineTransform(in Matrix3x3 linearTransform, in Vector3 translation)
        {
            LinearTransform = linearTransform;
            Translation = translation;

        }

        /// <摘要>
        /// 通过仿射变换变换向量。
        /// </Summary>
        /// <param name="position">要转换的位置。</param>
        /// <param name="Transform">要应用的转换。</param>
        /// <param name="Transform">转换位置。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Transform(in Vector3 position, in AffineTransform transform, out Vector3 transformed)
        {
            Matrix3x3.Transform(position, transform.LinearTransform, out transformed);
            transformed += transform.Translation;
        }

        /// <摘要>
        /// 反转仿射变换。
        /// </Summary>
        /// <param name="Transform">转换为反转。</param>
        /// <param name="Inverse">转换的反转。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Invert(in AffineTransform transform, out AffineTransform inverse)
        {
            Matrix3x3.Invert(transform.LinearTransform, out inverse.LinearTransform);
            Matrix3x3.Transform(transform.Translation, inverse.LinearTransform, out inverse.Translation);
            inverse.Translation = -inverse.Translation;
        }

        /// <摘要>
        /// 反转刚性变换。
        /// </Summary>
        /// <param name="Transform">转换为反转。</param>
        /// <param name="Inverse">转换的反转。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void InvertRigid(in AffineTransform transform, out AffineTransform inverse)
        {
            Matrix3x3.Transpose(transform.LinearTransform, out inverse.LinearTransform);
            Matrix3x3.Transform(transform.Translation, inverse.LinearTransform, out inverse.Translation);
            inverse.Translation = -inverse.Translation;
        }

        /// <summary>
        /// 将一个变换乘以另一个变换。
        /// </summary>
        /// <param name="a">第一个转换。</param>
        /// <param name="b">第二次转换。</param>
        /// <param name="Transform">组合转换。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Multiply(in AffineTransform a, in AffineTransform b, out AffineTransform transform)
        {
            Matrix3x3.Transform(a.Translation, b.LinearTransform, out var translation);
            transform.Translation = b.Translation + translation;
            Matrix3x3.Multiply(a.LinearTransform, b.LinearTransform, out transform.LinearTransform);
        }



    }
}
